package org.iabako.client.ui.page.business.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.EventListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import org.iabako.client.config.page.PageConfigSearchEnum;
import org.iabako.client.config.page.PageEnum;
import org.iabako.client.navigation.NavigationController;
import org.iabako.client.tools.DefaultSuggestHandler;
import org.iabako.client.tools.IabakoAsyncCallback;
import org.iabako.client.tools.Messages;
import org.iabako.client.ui.form.business.client.ClientSearchForm;
import org.iabako.client.ui.layout.field.Button;
import org.iabako.client.ui.layout.widget.datatable.DataTable;
import org.iabako.client.ui.layout.widget.tooltip.TooltipListener;
import org.iabako.client.ui.page.AbstractSearchPage;
import org.iabako.client.user.AuthenticateUserProvider;
import org.iabako.shared.entity.enumeration.NotificationType;
import org.iabako.shared.entity.enumeration.TrackingType;
import org.iabako.shared.iservice.business.ClientServiceAsync;
import org.iabako.shared.iservice.business.CommunicationServiceAsync;
import org.iabako.shared.iservice.business.SaleEnMasseServiceAsync;
import org.iabako.shared.iservice.generic.CRUDServiceAsync;
import org.iabako.shared.iservice.generic.SearchServiceAsync;
import org.iabako.shared.iservice.generic.SuggestServiceAsync;
import org.iabako.shared.querydefinition.columndefinition.ClientColumnEnum;
import org.iabako.shared.querydefinition.dto.QueryDefinitionDTO;
import org.iabako.shared.querydefinition.dto.QueryOperatorEnum;

/**
 * TODO javadoc
 * Date: 24/11/13
 * Time: 17:15
 */
public class ClientSearch extends AbstractSearchPage {

    interface MyUiBinder extends UiBinder<HTMLPanel, ClientSearch> {
    }

    private static final MyUiBinder binder = GWT.create(MyUiBinder.class);

    protected final CommunicationServiceAsync communicationServiceAsync = CommunicationServiceAsync.Util.getInstance();
    protected final SaleEnMasseServiceAsync saleEnMasseServiceAsync = SaleEnMasseServiceAsync.Util.getInstance();

    @UiField
    HTMLPanel clientSearchPanel;
    @UiField
    HTMLPanel resultsPanel;

    public ClientSearchForm clientSearchForm;

    //For communication purpose
    private QueryDefinitionDTO queryDefinitionDTOFromDataTable;

    public ClientSearch() {
        super(false);

        Button createClient = new Button("pageactionbutton", "client_create_title");
        page.actionButtons.add(createClient);

        createClient.getButton().addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                NavigationController.getInstance().goTo(PageEnum.ClientCreate);
            }
        });
    }

    @Override
    protected SearchServiceAsync getSearchServiceAsync() {
        return ClientServiceAsync.Util.getInstance();
    }

    @Override
    protected CRUDServiceAsync getCRUDServiceAsync() {
        return ClientServiceAsync.Util.getInstance();
    }

    @Override
    protected SuggestServiceAsync getSuggestServiceAsync() {
        return ClientServiceAsync.Util.getInstance();
    }

    @Override
    protected HTMLPanel getResultsPanel() {
        return resultsPanel;
    }

    @Override
    protected HTMLPanel getSearchPanel() {
        return clientSearchPanel;
    }

    @Override
    protected HTMLPanel getContentPanel() {
        return binder.createAndBindUi(this);
    }

    @Override
    protected DataTable getCustomDataTable() {

        DataTable dataTable = new DataTable(getSearchServiceAsync(), getCRUDServiceAsync(),
                getQueryDefinitionDTO(), getModificationPage(), getSearchPageConfigEnum()) {

            @Override
            protected void customTaskAfterRender() {
                queryDefinitionDTOFromDataTable = queryDefinitionDTO;
            }

            @Override
            protected void removeSuccessCustomAction() {
                dataTableRemoveCustomAction();
            }
        };

        return dataTable;
    }

    @Override
    protected void dataTableRemoveCustomAction() {
        AuthenticateUserProvider.getNotificationPanel().refresh(NotificationType.birthday,
                NotificationType.futureInstallments, NotificationType.newPastInstallments, NotificationType.paymentRequest);
        AuthenticateUserProvider.getTrackingPanel().refresh(TrackingType.clientDelete);
    }

    @Override
    protected Composite getSearchForm(DataTable dataTable) {

        if (clientSearchForm == null) {

            addSaleEnMasseButton(dataTable);
            addCommunicationsButton(dataTable);

            clientSearchForm = new ClientSearchForm(new DefaultSuggestHandler(getSuggestServiceAsync()), dataTable);
        }

        return clientSearchForm;
    }

    private void addCommunicationsButton(DataTable dataTable) {
        HTMLPanel communicationsAction = new HTMLPanel("<div class=\"communicationsicon\">");
        dataTable.customFooterActions.add(communicationsAction);
        DOM.sinkEvents(communicationsAction.getElement().getFirstChildElement(), Event.ONCLICK | Event.MOUSEEVENTS);
        DOM.setEventListener(communicationsAction.getElement().getFirstChildElement(), new SendCommunicationAction());
    }

    private class SendCommunicationAction implements EventListener {

        TooltipListener tooltipListener;

        private SendCommunicationAction() {
            tooltipListener = new TooltipListener(Messages.getLabel("communications_tooltip_text"));
        }

        public void onBrowserEvent(Event event) {
            switch (event.getTypeInt()) {
                case Event.ONCLICK:
                    communicationServiceAsync.prepareEnMasseAction(queryDefinitionDTOFromDataTable, new IabakoAsyncCallback<String>() {
                        public void onSuccess(String result) {
                            NavigationController.getInstance().goTo(PageEnum.CommunicationCreate, result);
                            super.onSuccess(result);
                        }
                    });
                    break;
                case Event.ONMOUSEOVER:
                case Event.ONMOUSEOUT:
                    tooltipListener.onBrowserEvent(event);
                    break;
            }
        }
    }

    private void addSaleEnMasseButton(DataTable dataTable) {
        HTMLPanel communicationsAction = new HTMLPanel("<div class=\"salesenmasseicon\">");
        dataTable.customFooterActions.add(communicationsAction);
        DOM.sinkEvents(communicationsAction.getElement().getFirstChildElement(), Event.ONCLICK | Event.MOUSEEVENTS);
        DOM.setEventListener(communicationsAction.getElement().getFirstChildElement(), new SaleEnMasseAction());
    }

    private class SaleEnMasseAction implements EventListener {

        TooltipListener tooltipListener;

        private SaleEnMasseAction() {
            tooltipListener = new TooltipListener(Messages.getLabel("sales_en_masse_tooltip_text"));
        }

        public void onBrowserEvent(Event event) {
            switch (event.getTypeInt()) {
                case Event.ONCLICK:
                    saleEnMasseServiceAsync.prepareEnMasseAction(queryDefinitionDTOFromDataTable, new IabakoAsyncCallback<String>() {
                        public void onSuccess(String result) {
                            NavigationController.getInstance().goTo(PageEnum.SaleMake, result);
                            super.onSuccess(result);
                        }
                    });
                    break;
                case Event.ONMOUSEOVER:
                case Event.ONMOUSEOUT:
                    tooltipListener.onBrowserEvent(event);
                    break;
            }
        }
    }

    @Override
    protected PageConfigSearchEnum getSearchPageConfigEnum() {
        return PageConfigSearchEnum.ClientSearch;
    }

    @Override
    protected PageEnum getModificationPage() {
        return PageEnum.ClientModify;
    }

    @Override
    protected QueryDefinitionDTO getQueryDefinitionDTO() {
        QueryDefinitionDTO queryDefinitionDTO = new QueryDefinitionDTO();
        queryDefinitionDTO.addCriteria(ClientColumnEnum.disabled, QueryOperatorEnum.EQUALS, false);
        return queryDefinitionDTO;
    }

}
